﻿using System.CodeDom;
using InterfaceWeaver.AopCore;
using Roslyn.Compilers.CSharp;
using System.Linq;

namespace InterfaceWeaver.CustomTool
{
    public sealed class InterfaceDeclaration
    {
        private readonly InterfaceDeclarationSyntax @interface = null;

        /// <summary>
        /// Initializes a new instance of the <see cref="InterfaceDeclaration" /> class.
        /// </summary>
        /// <param name="interface">The interface.</param>
        public InterfaceDeclaration(InterfaceDeclarationSyntax @interface)
        {
            this.@interface = @interface;
        }

        /// <summary>
        /// Creates the code type implementation.
        /// </summary>
        /// <returns></returns>
        public CodeTypeDeclaration CreateCodeTypeImplementation()
        {
            var interfaceName = @interface.Identifier.ValueText;
            string typeName = null;
            var optionsAttribute = @interface.AttributeLists
                .SelectMany(attribute => attribute.Attributes)
                .FirstOrDefault(attribute => attribute.IsOfType<WeaverOptionsAttribute>());

            if (optionsAttribute != null && optionsAttribute.HasParameter("TypeName"))
            {
                typeName = optionsAttribute.GetParameterValue<string>("TypeName");
            }
            else
            {
                typeName = interfaceName.StartsWith("I")
                                ? @interface.Identifier.ValueText.TrimStart('I')
                                : interfaceName + "Implementation";
            }
            
            string genericParametersText = null;
            if(this.@interface.TypeParameterList != null 
                && this.@interface.TypeParameterList.Parameters.Any())
            {
                genericParametersText = string.Format("<{0}>", string.Join(", ", this.@interface.TypeParameterList.Parameters));
            }

            var weavedType = new CodeTypeDeclaration(typeName + genericParametersText)
            {
                IsClass = true,
                IsPartial = true
            };

            weavedType.BaseTypes.Add(new CodeTypeReference(@interface.Identifier.ValueText + genericParametersText));
            return weavedType;
        }
    }
}
